﻿using System;
using System.Collections.Generic;
using System.ServiceModel;
using System.Linq;

using SharedGenomics.Core;
using SharedGenomics.Domain;
using SharedGenomics.DataTransfer;
using SharedGenomics.Workbench.Core;

namespace SharedGenomics.Workbench.Services
{
    public class WCFSnpService : WCFClientHost, ISnpService
    {
        public Maybe<IEnumerable<string>> FilterUnavailableMarkers(IEnumerable<string> markers)
        {
            return this.ExecuteProxyContract<DataService.IDataService, IEnumerable<string>>(ds => ds.GetUnavailableMarkers(markers.ToArray())).Just();
        }

        public Maybe<bool> SetUserMarker(string markerName, int rsNumber, out int chromosome, out long position, out string errorMessage)
        {
            errorMessage = String.Empty;
            chromosome = 0;
            position = 0;

            try
            {
                Map addedSnp = this.ExecuteProxyContract<DataService.IDataService, Map>(ds => ds.AddGroupMarkerByRsNumber(markerName, rsNumber));

                chromosome = (int)addedSnp.Chromosome;
                position = addedSnp.BasePosition;
                return true.Just();
            }
            catch (FaultException<DuplicateGroupMarkerFaultMessage> ex)
            {
                errorMessage = this.GetDuplicateMarkerErrorMessage(ex.Detail);
            }
            catch (FaultException<SnpNotFoundFaultMessage> ex)
            {
                errorMessage = String.Format("SNP with rs number {0} not found", ex.Detail.RsNumber);
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
            }

            return false.Just();
        }

        public Maybe<bool> SetUserMarker(string markerName, int chromosomeIndex, long position, out string errorMessage)
        {
            try
            {
                this.ExecuteProxyContract<DataService.IDataService>(ds =>
                {
                    ds.AddGroupMarkerBySnpDetails(markerName, (short)chromosomeIndex, position);
                });

                errorMessage = String.Empty;
                return true.Just();
            }
            catch (FaultException<DuplicateGroupMarkerFaultMessage> ex)
            {
                errorMessage = this.GetDuplicateMarkerErrorMessage(ex.Detail);
            }
            catch (Exception ex)
            {
                errorMessage = ex.Message;
            }

            return false.Just();
        }

        private string GetDuplicateMarkerErrorMessage(DuplicateGroupMarkerFaultMessage faultMessage)
        {
            return String.Format("Group already has a definition for marker '{0}'", faultMessage.MarkerName ?? "<null>");
        }
    }
}
